/** @format */

"use strict"

import axios from "axios"
// import cookie from "js-cookie"
import utils from "_libs/utils"
import apiData from "./apiList"
import config from "../config"

axios.defaults.baseURL = config.apiDomainList.pageBaseUrl // 基本路径
// axios.defaults.headers["x-csrf-token"] = cookie.get("csrfTokenFeplatform") || ""

let axiosPromiseArr = []
// 获取CancelToken
axios.interceptors.request.use(
    function (config) {
        config.cancelToken = new axios.CancelToken(cancel => {
            axiosPromiseArr.push({cancel})
        })
        return config
    },
    function (error) {
        return Promise.reject(error)
    }
)
axios.interceptors.response.use(
    function (response) {
        return response
    },
    function (err) {
        let ret = {code: 400, msg: "未知错误"}
        if (axios.isCancel(err)) {
            // 取消请求的情况下，终端Promise调用链
            return new Promise(() => {
            })
        } else {
            if (err.response) {
                let {data = {}, status} = err.response
                ret.code = status
                switch (status) {
                    case 400:
                        ret.msg = "请求错误"
                        break
                    case 403:
                        ret.msg = "权限不足拒绝访问"
                        break
                    case 404:
                        ret.msg = "接口找不到了"
                        break
                    case 500:
                        ret.msg = "服务器内部错误"
                        break
                    case 408:
                        err.msg = "请求超时"
                        break
                    case 501:
                        err.msg = "服务未实现"
                        break
                    case 502:
                        ret.msg = "网关错误"
                        break
                    case 503:
                        ret.msg = "服务不可用"
                        break

                    case 504:
                        ret.msg = "网关超时"
                        break
                    case 505:
                        ret.msg = "HTTP版本不受支持"
                        break
                    default:
                        data.success !== "" && delete data.success
                        ret = data
                }
            }
        }
        return Promise.reject(ret)
    }
)


const getGatewayPath = function (apiName) {
    /**
     * 1. 默认admin 服务 前端可指定其他服务 后端需要验证下
     * 2. 根据动态参数最多三个 p1 p2 p3
     * 3. 调用方式 getGatewayPath({
                name: "test",
                type: "PICK_ADMIN",
                p1: "fuck",
                p2: "you",
            })

     4. getGatewayPath("test2") // 默认不带参数的是AMDIN的apis
     * */
    let newName = ""
    let apiType = "ADMIN"
    if (typeof apiName === "object") {
        let {name, type = "ADMIN", p1 = "", p2 = "", p3 = ""} = apiName
        newName = `/api/__proxy?__gateway_method_id=${name}&__gateway_place=${type}${
            p1 !== "" ? "&__gateway_p1=" + p1 : ""
            }${p2 !== "" ? "&__gateway_p2=" + p2 : ""}${p3 !== "" ? "&__gateway_p3=" + p3 : ""}`
    } else if (typeof apiName === "string") {
        newName = `/api/__proxy?__gateway_method_id=${apiName}&__gateway_place=${apiType}`
    } else {
        console.error("参数不合法,请检查后重试")
    }
    return newName
}
const delBlank = function (stringData) {
    return stringData.replace(/\s/g, "")
}
const getPath = apiName => {
    let currentApiConstName, currentRequestUrl
    const apiObj = utils.isObj(apiName)
    const apiString = utils.isString(apiName)
    if (apiObj || apiString) {
        currentApiConstName = delBlank(apiObj ? apiName.key : apiString ? apiName : apiName)
    } else {
        console.error(`apiName 不能为空并且 apiName要在apiData/index.js 文件中定义哟~`)
        return
    }
    if (currentApiConstName && apiData.hasOwnProperty(currentApiConstName)) {
        currentRequestUrl = apiData[currentApiConstName]
        if (apiObj) {
            //     进行替换工作
            currentRequestUrl = currentRequestUrl.replace(/[$]p[1-3][$]/g, value => {
                return apiName[value.replace(/[$]/g, "")].toString() || ""
            })
        }
    } else {
        console.error(`currentApiConstName 未在定义文件中找到，请在/apiData/index.js 中先定义再使用`)
        return
    }
    return currentRequestUrl
}

const handleResponse = function (request) {
    return new Promise((resolve, reject) => {
        const errHandle = data => {
            console.log("data", data)
            if (data.code === 401) {
                // 删除正在进行中的请求
                axiosPromiseArr.forEach(ele => ele.cancel())
                axiosPromiseArr = []
                window.location.reload()
            } else if (data.code === 403) {
                window.location.reload()
            } else if (data.code === 404) {
                // 接口 404
                console.log("接口404")
                reject(data)
            } else {
                reject(data)
            }
        }
        request
            .then(res => {
                if (res.data.code === 0) {
                    resolve(res.data)
                } else {
                    errHandle(res.data)
                }
            })
            .catch(err => {
                errHandle(err)
            })
    })
}
export default {
    get(apiName, params = {}) {
        return handleResponse(axios.get(getPath(apiName), {params}))
    },
    post(apiName, ...args) {
        return handleResponse(axios.post(getPath(apiName), ...args))
    },
    put(apiName, ...args) {
        return handleResponse(axios.put(getPath(apiName), ...args))
    },
    patch(apiName, ...args) {
        return handleResponse(axios.patch(getPath(apiName), {...args}))
    },
    delete(apiName, params = {}) {
        return handleResponse(axios.delete(getPath(apiName), {params}))
    },
    // node 做后端转发并且返回值做统一包装
    gateway: {
        get(apiName, ...args) {
            return handleResponse(axios.get(getGatewayPath(apiName), {...args}))
        },

        post(apiName, ...args) {
            return handleResponse(axios.post(getGatewayPath(apiName), ...args))
        },

        put(apiName, ...args) {
            return handleResponse(axios.put(getGatewayPath(apiName), ...args))
        },

        delete(apiName, ...args) {
            return handleResponse(axios.delete(getGatewayPath(apiName), {...args}))
        }
    },
    request(...args) {
        return axios(...args)
    }
}
